package cn.iocoder.yudao.module.fengdong.smartelderly.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import lombok.SneakyThrows;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * 生成二维码
 */
public class QRCodeGeneratorUtil {


    public static void main(String[] args) {
        byte[] generateQRCode =  QRCodeGeneratorUtil.generateQRCode("fmQrcodeUrl", "1","中铁十二局承建");
        String outPath = "E:\\宝塔备份\\java";
        String fileName = "1.png";
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try {
            File dir = new File(outPath);
            if (!dir.exists() && dir.isDirectory()) { //判断文件目录是否存在
                dir.mkdirs();
            }
            file = new File(outPath + File.separator + fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(generateQRCode);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }

    }

    @SneakyThrows
    public static byte[] generateQRCode(String url, String text1, String text2) {
        // 二维码宽高
        int width = 800;
        int height = 800;

        // 二维码宽高
        int codeWidth = width;
        int codeHeight = height;

        // 文字宽高 (自动计算)
        int textLength = text1.length();
        int textHeight = textLength + 80 + (textLength < 25 ? 0 : ((textLength / 6) * (textLength < 60 ? 10 : 15)));

        textHeight = textHeight + 15;// 加上第二文本的高度
        System.out.println("数字长度： " + textLength);
        System.out.println("textHeight: " + textHeight);

        int textWidth = width;
        int textMaxWidth = 800;

        // 文字区域最大宽度
        int imageHeight = codeHeight + textHeight;

        BufferedImage image = new BufferedImage(width, imageHeight, BufferedImage.TYPE_INT_RGB);

        // 二维码
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.MARGIN, 1);
        BitMatrix bitMatrix = qrCodeWriter.encode(url, BarcodeFormat.QR_CODE, width, height, hints);

        for (int i = 0; i < codeWidth; i++) {
            for (int j = 0; j < codeHeight; j++) {
                image.setRGB(i, j, bitMatrix.get(i, j) ? Color.BLACK.getRGB() : Color.WHITE.getRGB());
            }
        }

        // 添加文字
        Graphics2D graphics = image.createGraphics();
        //开启文字抗锯齿
        graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        // 设置背景颜色
        graphics.fillRect(0, codeHeight, textWidth, textHeight);

        // 设置字体颜色和样式
        graphics.setColor(Color.BLACK);
        Font font = new Font("宋体", Font.BOLD, 48);
        graphics.setFont(font);

        // 计算文字的宽度和高度
        FontMetrics fontMetrics = graphics.getFontMetrics();
        int lineHeight = fontMetrics.getHeight();

        // 计算每行文字的起始位置和行高
        {
            int x = 30;
            if (graphics.getFontMetrics().stringWidth(text1) < textMaxWidth){
                x = (textMaxWidth - fontMetrics.stringWidth(text1)) / 2;
            }else{
                textMaxWidth = 720;
            }
            int y = imageHeight-30 + (height - imageHeight - fontMetrics.getHeight() * getLineCount(text1, fontMetrics, textMaxWidth)) / 2 + fontMetrics.getAscent();

            // 绘制文字
            drawWrappedText(graphics, text1, x, y, textMaxWidth, lineHeight);
        }

        {
            Font font2 = new Font("宋体", Font.BOLD, 48);
            graphics.setFont(font2);
            int x = 40;
            if (graphics.getFontMetrics().stringWidth(text2) < textMaxWidth){
                textMaxWidth = 800;
                x = (textMaxWidth - fontMetrics.stringWidth(text2)) / 2;
            }else{
                textMaxWidth = 720;
            }
            int y = imageHeight-20;

            // 绘制文字
            drawWrappedText(graphics, text2, x, y, textMaxWidth, lineHeight);
        }

        graphics.dispose();

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ImageIO.write(image, "png", byteArrayOutputStream);
        return byteArrayOutputStream.toByteArray();
    }


    // 绘制自动居中换行的文字
    private static void drawWrappedText(Graphics2D graphics, String text, int x, int y, int maxWidth, int lineHeight) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < text.length(); i++) {
            char ch = text.charAt(i);
            sb.append(ch);
            if (graphics.getFontMetrics().stringWidth(sb.toString()) >= maxWidth) {
                graphics.drawString(sb.toString(), x, y);
                y += lineHeight;
                sb.setLength(0);
            }
        }
        graphics.drawString(sb.toString(), x, y);
    }

    // 计算文本的行数
    private static int getLineCount(String text, FontMetrics fontMetrics, int maxWidth) {
        int count = 1;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < text.length(); i++) {
            char ch = text.charAt(i);
            sb.append(ch);
            if (fontMetrics.stringWidth(sb.toString()) > maxWidth) {
                count++;
                sb.setLength(0);
            }
        }
        return count;
    }


}
